package com.intelligent.ispc.web.controller;

import com.intelligent.ispc.common.dto.JsonPageResponseDto;
import com.intelligent.ispc.common.dto.JsonResponseDto;
import com.intelligent.ispc.common.utils.ApplicationException;
import com.intelligent.ispc.common.utils.ExceptionMessages;
import com.intelligent.ispc.common.web.Servlets;
import com.intelligent.ispc.core.dto.GroupDto;
import com.intelligent.ispc.core.dto.ProjectDto;
import com.intelligent.ispc.core.dto.UserDto;
import com.intelligent.ispc.core.service.GroupService;
import com.intelligent.ispc.utils.SystemConfig;
import com.intelligent.ispc.web.utils.PageUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * Created by dmsoft on 2016/5/4.
 */

@Controller
@RequestMapping(value = "/group")
public class GroupController {

    @Autowired
    private GroupService groupService;
    @Autowired
    private SystemConfig systemConfig;

    @RequestMapping(value = "", method = RequestMethod.GET)
    public String nav(Model model, ServletRequest request) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("system:group:view")) {
            return "error/noPermission";
        }
        return "group/groupList";
    }


    @ResponseBody
    @RequestMapping(value = "/list")
    public JsonPageResponseDto list(Model model, ServletRequest request) {

        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("system:group:view")) {
            return JsonPageResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }

        Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");

        Page<GroupDto> page = groupService.searchGroup(searchParam, PageUtil.buildPageWithParameters(request, systemConfig.getPageSize(), "name"));
        List<GroupDto> groups1 = page.getContent();
        JsonPageResponseDto json = JsonPageResponseDto.SUCCESS().setBody(groups1);
        json.setRecordsTotal(page.getTotalElements());
        json.setRecordsFiltered(page.getTotalElements());
        json.setDraw(0);

        return json;
    }

    @RequestMapping(value = "register", method = RequestMethod.GET)
    public String registerForm(Model model) {

        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("system:group:create")) {
            return "error/noPermission";
        }
        return "group/createGroup";
    }

    @ResponseBody
    @RequestMapping(value = "createGroup", method = RequestMethod.POST)
    public JsonResponseDto register(GroupDto groupDto, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:group:create")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }
            groupService.saveGroup(groupDto);
        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
        return JsonResponseDto.SUCCESS();
    }

    @RequestMapping(value = "find", method = RequestMethod.POST)
    public JsonResponseDto find(Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("system:group:view")) {
            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }
        List<GroupDto> groupDto = groupService.findAllGroups();

        return JsonResponseDto.SUCCESS().setBody(groupDto);
    }

    @ResponseBody
    @RequestMapping(value = "isExistGroupName", method = RequestMethod.POST)
    public boolean isExistGroupName(Model model, HttpServletRequest request) {

        try {
            groupService.isExistGroupName(request.getParameter("groupName"));
        } catch (ApplicationException ex) {
            return false;
        }
        return true;
    }

    @ResponseBody
    @RequestMapping(value = "checkGroupName", method = RequestMethod.POST)
    public boolean checkGroupName(Model model, HttpServletRequest request) {

        String name = request.getParameter("groupName");
        Long id = Long.valueOf(request.getParameter("groupId"));

        try {
            groupService.checkGroupName(id, name);
        } catch (ApplicationException ex) {
            return false;
        }
        return true;
    }

    @RequestMapping(value = "edit/{id}", method = RequestMethod.GET)
    public String editForm(@PathVariable("id") String id, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("system:group:edit")) {
            return "error/noPermission";
        }
        GroupDto groupDto = groupService.findById(id);
        model.addAttribute("group",groupDto);
        return "group/groupDetail";
    }

    @ResponseBody
    @RequestMapping(value = "update{id}", method = RequestMethod.GET)
    public JsonResponseDto updateForm(@PathVariable("id") String id, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("system:group:view")) {
            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }
        return JsonResponseDto.SUCCESS().setBody(groupService.findById(id));
    }

    @ResponseBody
    @RequestMapping(value = "update", method = RequestMethod.POST)
    public JsonResponseDto update(@ModelAttribute("group") GroupDto groupDto, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("system:group:edit")) {
            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }
        groupService.updateGroup(groupDto);
        return JsonResponseDto.SUCCESS();
    }

    @ResponseBody
    @RequestMapping(value = "delete/{id}")
    public JsonResponseDto delete(@PathVariable("id") String id, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:group:delete")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            groupService.deleteGroup(id);
        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
        return JsonResponseDto.SUCCESS();
    }

    @ModelAttribute
    public void getUser(@RequestParam(value = "id", defaultValue = "") String id, Model model) {
        if (StringUtils.isNotBlank(id)) {
            model.addAttribute("group", groupService.findById(id));
        }
    }

    @ResponseBody
    @RequestMapping(value = "findProjectsForNotInThisGroup")
    public JsonResponseDto findProjectsForNotInThisGroup(ServletRequest request, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:group:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            String id = request.getParameter("id");
            List<ProjectDto> list = groupService.findProjectsForNotInThisGroup(id);

            return JsonResponseDto.SUCCESS().setBody(list);

        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
    }

    @ResponseBody
    @RequestMapping(value = "findUsersForNotInThisGroup")
    public JsonResponseDto findUsersForNotInThisGroup(ServletRequest request, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:group:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            String id = request.getParameter("id");
            List<UserDto> list = groupService.findUsersForNotInThisGroup(id);

            return JsonResponseDto.SUCCESS().setBody(list);

        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
    }

    @ResponseBody
    @RequestMapping(value = "assignProjects")
    public JsonResponseDto assignProjects(@RequestParam("groupId") String groupId, @RequestParam("projectIds") List<String> projectIds, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:group:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            groupService.assignProjectsForGroup(groupId,projectIds);

            return JsonResponseDto.SUCCESS();

        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
    }

    @ResponseBody
    @RequestMapping(value = "assignUsers")
    public JsonResponseDto assignUsers(@RequestParam("groupId") String groupId, @RequestParam("userIds") List<String> userIds, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:group:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            groupService.assignUsersForGroup(groupId,userIds);

            return JsonResponseDto.SUCCESS();

        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
    }

    @ResponseBody
    @RequestMapping(value = "deleteProject")
    public JsonResponseDto deleteProject(@RequestParam("groupId") String groupId, @RequestParam("projectIds") List<String> projectIds, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:group:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            groupService.deleteProjectsForGroup(groupId,projectIds);

            return JsonResponseDto.SUCCESS();

        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
    }

    @ResponseBody
    @RequestMapping(value = "deleteUser")
    public JsonResponseDto deleteUser(@RequestParam("groupId") String groupId, @RequestParam("userIds") List<String> userIds, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:group:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            groupService.deleteUsersForGroup(groupId,userIds);

            return JsonResponseDto.SUCCESS();

        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
    }

    @ResponseBody
    @RequestMapping(value = "findUsersForGroupByName")
    public JsonPageResponseDto findUsersForGroupByName(Model model, ServletRequest request) {

        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:group:view")) {
                return JsonPageResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");

            Page<UserDto> page = groupService.findUsersForGroupByName(searchParam, PageUtil.buildPageWithParameters(request, systemConfig.getPageSize(), "loginName"));
            List<UserDto> userDtoList = page.getContent();
            JsonPageResponseDto json = JsonPageResponseDto.SUCCESS().setBody(userDtoList);
            json.setRecordsTotal(page.getTotalElements());
            json.setRecordsFiltered(page.getTotalElements());
            json.setDraw(0);
            return json;

        } catch (ApplicationException ex) {
            return JsonPageResponseDto.FAILURE().setMessage(ex.getMessage());
        }
    }

    @ResponseBody
    @RequestMapping(value = "findProjectsForGroupByName")
    public JsonPageResponseDto findProjectsForGroupByName(Model model, ServletRequest request) {

        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:group:view")) {
                return JsonPageResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");

            Page<ProjectDto> page = groupService.findProjectsForGroupByName(searchParam, PageUtil.buildPageWithParameters(request, systemConfig.getPageSize(), "code"));
            List<ProjectDto> projectDtoList = page.getContent();
            JsonPageResponseDto json = JsonPageResponseDto.SUCCESS().setBody(projectDtoList);
            json.setRecordsTotal(page.getTotalElements());
            json.setRecordsFiltered(page.getTotalElements());
            json.setDraw(0);
            return json;
        }
        catch (ApplicationException ex) {
            return JsonPageResponseDto.FAILURE().setMessage(ex.getMessage());
        }
    }
}
